/**
 * - 作者: DoooReyn
 * - 日期: 2023.10.29
 * - 名称: Strings
 * - 描述: 字符串辅助工具
 */
export class Strings {
    /**
     * @zh
     * 字符串格式化
     * @example
     * let s = "我叫{0}，我今年{1}岁"
     * let f = strings.format(s, "DoooReyn", "18")
     * console.log(f) // 我是DoooReyn，我今年18岁
     *
     * @return 格式化后的字符串
     */
    static format(str: string, ...args: any[]) {
        return str.replace(/\{(\d+)\}/g, (match, index) => {
            return index < args.length ? args[index] : match;
        });
    }

    /**
     * 解析 json 字符串
     * @param jsonStr json 字符串
     * @returns json数据
     */
    static asJsonObject(jsonStr: string) {
        let data = null;
        try {
            data = JSON.parse(jsonStr);
        } catch (err) {
            console.error('JSON parse error', err);
        }
        return data;
    }

    /**
     * 转换为JSON字符串
     * @param o 任意值
     * @returns
     */
    static asJsonString(o: any) {
        return JSON.stringify(o, null, 0);
    }

    /**
     * 获取字符串字节长度
     */
    static byteLength(s: string) {
        return encodeURI(s).split(/%..|./).length - 1;
    }

    /**
     * 数字转千分位字符串
     * @param num 数字
     * @returns 千分位字符串
     */
    static toThousand(num: number) {
        return (num | 0).toLocaleString('en-US');
    }

    /**
     * 去除除空格外的空字符
     * @param str 原始字符串
     * @returns 修正后的字符串
     */
    static trimNullChars(str: string) {
        return str.replace(/[\f\n\r\t\v\u1680\u180e\u2028\u2029\ufeff+]/g, '');
    }

    /**
     * 是否完全的中文字符串
     * @return 是否完全的中文字符串
     */
    static isChinese(str: string) {
        return /^[\u4E00-\u9FA5]+$/.test(str);
    }

    /**
     * 去除中文字符
     * @return 返回去除中文字符后的字符串
     */
    static removeChinese(str: string) {
        return str.replace(/[\u4E00-\u9FA5]+/gm, '');
    }

    /** 输入验证元素 */
    private static readonly AllowedProtocol: Readonly<string[]> = ['http:', 'https:', 'ws:', 'wss:'] as const;

    /**
     * 是否有效的网址
     * @param str 网址
     * @returns 是否有效的网址
     */
    static isValidURL(str: string) {
        try {
            return this.AllowedProtocol.indexOf(new URL(str).protocol) > -1;
        } catch {
            return false;
        }
    }

    /**
     * 字符串补位
     * @param isStart 前置或后置补位
     * @returns
     */
    private static padding(isStart: boolean) {
        return function (str: string, template: string, len: number) {
            const diff_len = (len | 0) - str.length;
            if (diff_len <= 0) return str;
            const count = (diff_len / template.length + 0.5) | 0;
            const filled = template.repeat(count).slice(0, diff_len);
            str = isStart ? filled + str : str + filled;
            return str;
        };
    }

    /**
     * 字符串前置补位
     * @param str 原始字符串
     * @param template 补位字符串模板
     * @param len 补位后字符串长度
     * @returns
     */
    static padStart = Strings.padding(true);

    /**
     * 字符串后置补位
     * @param str 原始字符串
     * @param template 补位字符串模板
     * @param len 补位后字符串长度
     * @returns
     */
    static padEnd = Strings.padding(false);
}
